/**
 * \class Randomizer.h /GenProg/RandomPkg/Randomizer.h
 *
 *  \date 15 nov 2012
 *  \author ytc0039
 *  
 *  \brief 
 */
#pragma once
#ifndef RANDOMIZER_H_
#define RANDOMIZER_H_
#include <Generator/TerminalState.h>
#include <Interfaces/Enumeration.h>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <RandomPkg/GeneratorBase.h>
#include <string>

/**
 * \brief
 *
 */
namespace RandomPkg {




class Randomizer : public GeneratorBase {
public:
	Randomizer()
	{};
	virtual ~Randomizer(){};


	template<class T> T createRandom();
	template<class T> T createRandom(T min,T max);
	template<class T> T createRandom(int min, int max);
	std::string generateRandomString(int minNrLetters,int maxNrLetters);

};



template<class T>
T Randomizer::createRandom()
{
	boost::random::uniform_int_distribution<> dist(0, T::size() - 1);
	T term = T::fromOrdinal( dist(gen) );
	return term;

}


template<class T>
T Randomizer::createRandom(T min,T max)
{
	boost::random::uniform_real_distribution<T> dist(min,max);
	return dist(gen);
}

template<class T>
T Randomizer::createRandom(int min,int max)
{

	boost::random::uniform_int_distribution<> dist(min, max);
	return dist(gen);
}


}

/**
 * \brief Randomization specialization
 *
 * Will choose a random item from a Enumeration
 * @see Enumeration
 * Template Specialization

template<>
class Randomizer< Enumeration<TerminalState> > : public GeneratorBase {
public:
	Randomizer(){

	};
	virtual ~Randomizer(){};

	TerminalState createRandom(){
			boost::random::uniform_int_distribution<> dist(0, Enumeration<TerminalState>::size() - 1);
			TerminalState term = Enumeration<TerminalState>::fromOrdinal( dist(gen) );
		return term;
	}



};


*/


/*
template <typename N> N getRandom(int min, int max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed((int)t.tv_sec);
  boost::uniform_int<> dist(min, max);
  boost::variate_generator<boost::mt19937&, boost::uniform_int<> > random(seed, dist);
  return random();
}
//! partial specialization for real numbers
template <typename N> N getRandom(N min, N max)
{
  timeval t;
  gettimeofday(&t,NULL);
  boost::mt19937 seed( (int)t.tv_sec );
  boost::uniform_real<> dist(min,max);
  boost::variate_generator<boost::mt19937&, boost::uniform_real<> > random(seed,dist);
  return random();
}
 */
#endif /* RANDOMIZER_H_ */
